package top.syfy.bili.fbm.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.setting.dialect.Props;
import top.syfy.bili.fbm.entry.Entry;
import top.syfy.bili.fbm.entry.PageData;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 * 对 entry.json 文件的属性及属性值的读写
 *
 * @author syfy
 * @date 2021/02/01
 */
public class EntryJSONUtil {

	/**
	 * 读取专辑配置文件,把获取到的值赋值给对应的专辑实体对象
	 *
	 * @param propertiesFile 与 entry.json 对应的 .properties 配置文件
	 * @param videoDir 专辑目录
	 */
	public static Entry parseEntryJSONFile(File propertiesFile, File videoDir) throws IOException {
		if (!FileUtil.exist(propertiesFile)) {
			throw new FileNotFoundException(propertiesFile.getAbsolutePath() + " 文件不存在");
		}
		if (!FileUtil.exist(videoDir)) {
			throw new FileNotFoundException(videoDir.getAbsolutePath() + " 文件不存在");
		}
		// 读取properties配置文件
		Props props = new Props(propertiesFile, StandardCharsets.UTF_8);
		props.autoLoad(true);
		// 判断给定的专辑是否是目录
		if (!FileUtil.isDirectory(videoDir)) {
			throw new IOException(videoDir.getAbsolutePath() + " 应该是一个目录, 但它不是");
		}
		// 获取专辑下的所有子目录
		File[] subDirs = videoDir.listFiles(File::isDirectory);
		if (Objects.isNull(subDirs)) {
			throw new IOException("该目录下不存在缓存文件目录");
		}
		/*
			封装数据
		 */
		Arrays.sort(subDirs, Comparator.comparing(File::getName));
		Entry entry = new Entry();
		List<PageData> pds = new ArrayList<>();
		// 每一个专辑下的每一个子目录
		for (File sub : subDirs) {
			/* 选集和分集的情况下, 获取专辑信息 */
			File[] entryJsonFiles = Objects.requireNonNull(sub.listFiles(pathname -> props.getProperty("ENTRY_FILE").equals(pathname.getName())));
			if (entryJsonFiles.length < 1) {
				continue;
			}
			File entryJsonFile = entryJsonFiles[0];
			JSONObject jsonObject = JSONUtil.readJSONObject(entryJsonFile, StandardCharsets.UTF_8);
			// 视频的AV号
			String avId = jsonObject.getStr(props.getProperty("ENTRY_AVID"));
			// 视频的BV号
			String bvId = jsonObject.getStr(props.getProperty("ENTRY_BVID"));
			// 专辑名称
			String title = jsonObject.getStr(props.getProperty("ENTRY_TITLE"));
			// 视频质量
			Integer videoQuality = jsonObject.getInt(props.getProperty("ENTRY_VIDEO_QUALITY"));
			entry.setAvId(avId);
			entry.setBvId(bvId);
			entry.setTitle(title);
			entry.setVideoQuality(videoQuality);
			/* 分别在分集和选集的情况下获取对应的信息 */
			String basePath = new File(entryJsonFile.getParentFile(), String.valueOf(jsonObject.getInt(props.getProperty("ENTRY_VIDEO_QUALITY")))).getAbsolutePath() + File.separator;
			pds.add(parsePageDataPart(jsonObject, props, basePath));
		}
		// 对pds进行排序(按page属性值进行升序排序) - 即按照集数进行排序
		pds.sort(Comparator.comparingInt(PageData::getPage));
		entry.setPds(pds);
		return entry;
	}

	/**
	 * 读取entry.json文件的[page_data]部分的数据
	 *
	 * @param jsonObject JSON对象
	 * @param props Properties文件读取封装类
	 * @param basePath 音视频文件(audio.m4s,video.m4s)上层路径
	 * @return entry.json文件的[page_data]部分的Java对象
	 */
	private static PageData parsePageDataPart(JSONObject jsonObject, Props props, String basePath) {
		PageData pd = new PageData();
		JSONObject obj = JSONUtil.parseObj(jsonObject.get(props.getProperty("ENTRY_PAGE_DATA")));
		// cid
		Long cid = obj.getLong(props.getProperty("ENTRY_PAGE_DATA_CID"));
		// 集数
		Integer page = obj.getInt(props.getProperty("ENTRY_PAGE_DATA_PAGE"));
		// 集数标题
		String part = obj.getStr(props.getProperty("ENTRY_PAGE_DATA_PART"));
		pd.setCid(cid);
		pd.setPage(page);
		pd.setPart(part);
		pd.setVideoPart(basePath + props.getProperty("VIDEO_PART_FILE"));
		pd.setAudioPart(basePath + props.getProperty("AUDIO_PART_FILE"));
		return pd;
	}

}